import axios from 'axios';
import { getTokenAUTH } from '@/utils/auth';
/**
 * axios二次封装
 * @param {Object} axiosConfig axios配置
 * @param {Object} customOptions 个性化配置
 * @returns promise对象
 */
function myAxios(axiosConfig, customOptions) {
    // 创建axios实例
    const service = axios.create({
        baseURL: 'http://localhost:3300/api', // 设置统一的请求前缀
        timeout: 10000, // 设置统一的超时时长
    });

    // 自定义配置
    // assign用于合并两个对象
    // 如果有相同属性,就覆盖值
    // 没有相同属性，就添加属性和值
    let custom_options = Object.assign({
        reduct_data_format: true, // 是否开启简洁的数据结构响应, 默认为true
        error_message_show: true, // 是否开启接口错误信息展示,默认为true
        error_detail_show: true, // 是否开启接口错误详情展示,默认为true
        code_message_show: false, // 是否开启code不为0时的信息提示, 默认为false
    }, customOptions);

    // 请求拦截
    service.interceptors.request.use(
        config => {
            // 自动携带Token
            if (getTokenAUTH() && typeof window !== "undefined") {
                config.headers.Authorization = getTokenAUTH();
            }
            return config;
        },
        error => {
            return Promise.reject(error);
        }
    );

    // 响应拦截
    service.interceptors.response.use(

        // 成功的响应
        response => {
            if (custom_options.code_message_show && response.data && response.data.code !== 0) {
                ElMessage({
                    type: 'error',
                    message: response.data.message
                })
                return Promise.reject(response.data); // code不等于0, 页面具体逻辑就不执行了
            }

            return custom_options.reduct_data_format ? response.data : response; // 简洁数据结构响应
        },

        // 失败的响应
        error => {
            custom_options.error_message_show && httpErrorStatusHandle(error); // 处理错误状态码
            custom_options.error_detail_show && errorDetailHandle(error)
            return Promise.reject(error); // 错误继续返回给到具体页面
        }
    );
    // 将请求配置传递给axios实例，并返回promise对象
    return service(axiosConfig)
}

export default myAxios;

/**
 * 异常处理[功能]
 * @param {*} error promise rejected
 */
function httpErrorStatusHandle(error) {
    let message = '';
    if (error && error.response) {
        switch (error.response.status) {
            case 302: message = '接口重定向了！'; break;
            case 400: message = '参数不正确！'; break;
            case 401: message = '您未登录，或者登录已经超时，请先登录！'; break;
            case 403: message = '您没有权限操作！'; break;
            case 404: message = `请求地址出错: ${error.response.config.url}`; break; // 在正确域名下
            case 408: message = '请求超时！'; break;
            case 409: message = '系统已存在相同数据！'; break;
            case 500: message = '服务器内部错误！'; break;
            case 501: message = '服务未实现！'; break;
            case 502: message = '网关错误！'; break;
            case 503: message = '服务不可用！'; break;
            case 504: message = '服务暂时无法访问，请稍后再试！'; break;
            case 505: message = 'HTTP版本不受支持！'; break;
            default: message = '异常问题，请联系管理员！'; break
        }
    }
    if (error.message.includes('timeout')) message = '网络请求超时！';
    if (error.message.includes('Network')) message = window.navigator.onLine ? '服务端异常！' : '您断网了！';

    ElMessage({
        type: 'error',
        message
    })
}

/**
 * 错误详情中间件
 * @param {*} error promise rejected
 */
function errorDetailHandle(error) {
    let errorInfo = error.response.data.errors
    // 遍历errorInfo中的每一项
    errorInfo.forEach(function (item) {
        // 如果type为失败
        if (item.type == 'field') {
            // 弹出错误信息
            ElMessage({
                type: 'error',
                message: item.msg
            })
        }
    })
}